package com.sykj.seaflow.warm.core.convert2;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.sykj.seaflow.warm.core.constant.FlowConstant;
import com.sykj.seaflow.warm.core.listener.GlobalAssignmentListener;
import com.sykj.seaflow.warm.core.listener.GlobalCreateListener;
import com.sykj.seaflow.warm.module.def.bean.SeaFlowNode;
import org.dromara.warm.flow.core.constant.FlowCons;
import org.dromara.warm.flow.core.entity.Node;
import org.dromara.warm.flow.core.entity.Skip;
import org.dromara.warm.flow.core.enums.NodeType;
import org.dromara.warm.flow.core.enums.SkipType;
import org.dromara.warm.flow.core.listener.Listener;
import org.dromara.warm.flow.orm.entity.FlowSkip;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

public class BetweenNodeConvert extends NodeConvertAbstract {
    @Override
    public List<Node> convert(SeaFlowNode parentNode,JSONObject jsonNode, String startNodeId, String endNodeId, String lastLineNodeId) {
        SeaFlowNode seaFlowNode = getNode(jsonNode);
        JSONObject config = jsonNode.getJSONObject("properties");
        seaFlowNode.setBackType(config.getStr("backType"));
        seaFlowNode.setBackTypeNode(config.getStr("backTypeNode"));
        seaFlowNode.setFieldSetting(config.getStr("fieldSetting"));
        List<Skip> skipList = new ArrayList<>();
        JSONObject childNode = jsonNode.getJSONObject("childNode");
        String betweenEndNode =  childNode == null? lastLineNodeId :  childNode.getStr("nodeId");
        String formPath = config.getStr("formPath");
        if(ObjectUtil.isNotEmpty(formPath)){
            seaFlowNode.setFormPath(formPath);
        }

        // 监听器
        JSONArray jsonArray = config.getJSONArray("listeners");
        StringBuilder listenerType = new StringBuilder(String.join(",", Listener.LISTENER_ASSIGNMENT, Listener.LISTENER_CREATE));
        StringBuilder listenerPath = new StringBuilder(String.join("@@", GlobalAssignmentListener.class.getName(),
                GlobalCreateListener.class.getName()));
        if(jsonArray != null && jsonArray.size() > 0){
            for (int i = 0; i < jsonArray.size(); i++) {
                listenerType.append(",").append(jsonArray.get(i, JSONObject.class).getStr("listenerType"));
                listenerPath.append(FlowCons.splitAt).append(jsonArray.get(i, JSONObject.class).getStr("listenerPath"));
            }
        }
        seaFlowNode.setListenerType(listenerType.toString());
        seaFlowNode.setListenerPath(listenerPath.toString());
        //  设置跳转
        FlowSkip flowSkip = new FlowSkip();
        flowSkip.setNowNodeCode(seaFlowNode.getNodeCode());
        flowSkip.setNextNodeCode(betweenEndNode);
        flowSkip.setSkipType(SkipType.PASS.getKey());
        skipList.add(flowSkip);




        // 判断 是否存在回退
        String str = config.getStr("backType");
        String backNodeCode = ObjectUtil.equal(str, "1") ?startNodeId: null;

        // 结束节点， 先不跳转到最后的end节点， 自定义个,后面再看有什么区别
        String rejectNodeCode = UUID.randomUUID().toString();

        // 拒绝的跳转
        FlowSkip skipBack = new FlowSkip();
        skipBack.setSkipType(SkipType.REJECT.getKey());
        skipBack.setNextNodeCode(rejectNodeCode);
        skipList.add(skipBack);

        // 分支网关
        SeaFlowNode serialNode = rejectNode(rejectNodeCode, backNodeCode, endNodeId);


        seaFlowNode.setSkipList(skipList);
        List<Node> nodes = nextNode(seaFlowNode, childNode, startNodeId, endNodeId,lastLineNodeId);
        List<Node> list = new ArrayList<>();
        list.add(seaFlowNode);
        list.add(serialNode);
        list.addAll(nodes);
        return list;  //List.of( node);
    }

    @Override
    public String getType() {
        return "between";
    }


    private SeaFlowNode rejectNode(String rejectNode, String backNodeCode, String endNodeCode){

        SeaFlowNode serialNode = new SeaFlowNode();
        serialNode.setNodeCode(rejectNode);
        serialNode.setNodeRatio(BigDecimal.valueOf(0));
        serialNode.setNodeType(NodeType.SERIAL.getKey());

        List<Skip> skipList = new ArrayList<>();
        FlowSkip skipReject = new FlowSkip();
        skipReject.setSkipCondition( "@@reject@@|_of_reject@@eq@@1");
        skipReject.setSkipType(SkipType.REJECT.getKey());
        skipReject.setNextNodeCode(endNodeCode);
        skipList.add(skipReject);
        // 如果不为null ,回退节点
        if(ObjectUtil.isNotEmpty(backNodeCode)){
            FlowSkip skipBack = new FlowSkip();
            skipBack.setSkipCondition( "@@reject@@|_of_reject@@eq@@2");
            skipBack.setSkipType(SkipType.REJECT.getKey());
            skipBack.setNextNodeCode(backNodeCode);
            skipList.add(skipBack);
        }



        serialNode.setSkipList(skipList);
        return serialNode;
    }


}
